# SSAS - Simple Smart Automotive Software
# Copyright (C) 2023 Parai Wang <parai@foxmail.com>

import pprint
import os
import json
from .helper import *

__all__ = ['Gen']


def Gen_CDD_QueueEvent_cfg_INCLUDES(cfg, outfile):
    outfile.write(
        '/* ================================ [ INCLUDES  ] ============================================== */\n')
    outfile.write('#include "Cdd_QueueEvent_Type.h"\n')
    outfile.write("\n\n")

def Gen_CDD_QueueEvent_cfg_MACROS(cfg, outfile):
    outfile.write(
        '/* ================================ [ MACROS    ] ============================================== */\n')

    for Id, definition in enumerate(cfg['EventHandleMap']):
        outfile.write("#define      %s    %s \n" % (definition["EventId"], Id))

    outfile.write("\n\n")

    outfile.write("#define      %s_EVENT_ID_MAX     %d   " % (cfg['name'].upper(), len(cfg['EventHandleMap'])))


    outfile.write("\n\n")

def Gen_CDD_QueueEvent_cfg_TYPES(cfg, outfile):
    outfile.write(
        '/* ================================ [ TYPES     ] ============================================== */\n')

    outfile.write("""typedef void (*Event_Handler_Ptr) (void) ;""")

    outfile.write("\n\n")

    outfile.write("""typedef struct 
{
    // uint8_t EventId ;
    Event_Handler_Ptr Event_Handler_pFunc ;
}EventHandleCfg_T;  """)
    outfile.write("\n\n")
    pass

def Gen_CDD_QueueEvent_cfg_DECLARES(cfg, outfile):
    outfile.write(
        '/* ================================ [ DECLARES     ] ============================================== */\n')
    pass

def Gen_CDD_QueueEvent_cfg_DATAS(cfg, outfile):
    outfile.write(
        '/* ================================ [ DATAS     ] ============================================== */\n')

    outfile.write("extern  EventHandleCfg_T %s_EventHandleCfg[%s_EVENT_ID_MAX];"%(cfg["name"], cfg['name'].upper()))
    outfile.write("\n\n")
    pass

def Gen_CDD_QueueEvent_cfg_LOCALS(cfg, outfile):
    outfile.write(
        '/* ================================ [ LOCALS     ] ============================================== */\n')
    pass

def Gen_CDD_QueueEvent_cfg_FUNCTIONS(cfg, outfile):
    outfile.write(
        '/* ================================ [ FUNCTIONS     ] ============================================== */\n')

    for Id, definition in enumerate(cfg['EventHandleMap']):
        outfile.write("extern void %s(void); \n" % (definition["Event_Handler_Ptr"]))

    outfile.write("\n\nextern void %s_EventHandle(uint8_t EventId);" % (cfg["name"]))

    outfile.write("\n\n")


def Gen_CDD_QueueEvent_Cfg_H(cfg, dir):
    H = open('%s/%s_EventHandleCfg.h' % (dir, cfg["name"]), 'w')
    GenHeader(H)
    H.write('#ifndef __%s_CFG_H__\n' %(cfg["name"].upper()))
    H.write('#define __%s_CFG_H__\n' %(cfg["name"].upper()))

    Gen_CDD_QueueEvent_cfg_INCLUDES(cfg, H)

    Gen_CDD_QueueEvent_cfg_MACROS(cfg, H)

    # Gen_CDD_QueueEvent_cfg_TYPES(cfg, H)

    Gen_CDD_QueueEvent_cfg_DATAS(cfg, H)

    Gen_CDD_QueueEvent_cfg_FUNCTIONS(cfg, H)

    H.write('\n\n\n#endif /*  __%s_CFG_H__ */\n' %(cfg["name"].upper()))
    H.close()




def Gen_CDD_QueueEvent_Cfg_C_Execute(cfg, outfile):

    outfile.write("void %s_EventHandle(uint8_t EventId)"%(cfg["name"]))
    outfile.write("{\n\n")
    outfile.write("    /* Check EventId Range */\n")
    outfile.write("    if(EventId > %s_EVENT_ID_MAX)\n"%(cfg['name'].upper()))
    outfile.write("    {\n")
    outfile.write("        return;\n")
    outfile.write("    }\n\n")

    outfile.write("    /* Check FunctionPoint is NULL */\n")
    outfile.write("    if(%s_EventHandleCfg[EventId].Event_Handler_pFunc == NULL)\n"%(cfg['name']))
    outfile.write("    {\n")
    outfile.write("        return;\n")
    outfile.write("    }\n\n")
    outfile.write("    %s_EventHandleCfg[EventId].Event_Handler_pFunc();\n\n"%(cfg["name"]))
    outfile.write("}\n\n")

def Gen_CDD_QueueEvent_Cfg_C(cfg, dir):
    C = open('%s/%s_EventHandleCfg.c' % (dir, cfg["name"]), 'w')
    GenHeader(C)
    C.write(
        '/* ================================ [ INCLUDES  ] ============================================== */\n')
    C.write("#include \"%s_EventHandleCfg.h\""% (cfg["name"]))
    C.write("\n\n")

    C.write(
        '/* ================================ [ MACROS    ] ============================================== */\n')
    C.write("\n\n")

    C.write(
        '/* ================================ [ TYPES     ] ============================================== */\n')
    C.write("\n\n")

    C.write(
        '/* ================================ [ DECLARES  ] ============================================== */\n')
    C.write("\n\n")

    C.write(
        '/* ================================ [ DATAS     ] ============================================== */\n')
    C.write("EventHandleCfg_T %s_EventHandleCfg[%s_EVENT_ID_MAX] = \n" % (cfg["name"],  cfg['name'].upper()))
    C.write("{\n")
    for Id, definition in enumerate(cfg['EventHandleMap']):
        C.write("   {%s},// ID:%s\n" % ( definition["Event_Handler_Ptr"], definition["EventId"]))

    # C.write("\n\n   {EVENT_ID_INVALID ,NULL} \n} ;")
    C.write(" \n} ;\n")

    C.write(
        '/* ================================ [ LOCALS    ] ============================================== */\n')
    C.write("\n\n")

    C.write(
        '/* ================================ [ FUNCTIONS ] ============================================== */\n')
    Gen_CDD_QueueEvent_Cfg_C_Execute(cfg, C)


    C.write("\n\n")

    C.close()

def extract(cfg, dir):
    cfg_ = {}
    for k, v in cfg.items():
        if k not in ['durations']:
            cfg_[k] = v

    with open('%s/CDD_QueueEvent.json' % (dir), 'w') as f:
        json.dump(cfg_, f, indent=2)
    return cfg_


def Gen(cfg):
    try:
        dir = os.path.join(os.path.dirname(cfg), 'GEN')
        os.makedirs(dir, exist_ok=True)
        with open(cfg) as f:
            cfg = json.load(f)
        cfg_ = extract(cfg, dir)
        for sub_cfg in cfg_["CDD_QueueEvent"]:
            print(sub_cfg["name"])
            Gen_CDD_QueueEvent_Cfg_H(sub_cfg, dir)
            Gen_CDD_QueueEvent_Cfg_C(sub_cfg, dir)
    except Exception as e:
        print(e)
